Session Management in ASP.NET






4.03/5 (24 votes)
Jan 20, 2004
4 min read

247555
Explains cookie-based and cookie-less session management with the help of HTTP headers.
Title: Session Management in ASP.NET Author: Narendra Naidu Email: "mailto:naren@sulekha.com">naren@sulekha.com Environment: C#, ASP.NET 1.1 Keywords: Session Management, Cookies Level: Intermediate" Description: FONT-SIZE: 9pt">Explains cookie-based and cookie-less session management with the help of HTTP headers. Section Miscellaneous SubSection General
Introduction
Session Management is fundamental to any web application. In the article we shall try to understand what goes on beneath the hood of HTTP headers for session management.
Session management in ASP.NET can be done in two ways:
- Using Cookies
- Encoding of URLs with Session ID
Let’s try to understand both these methods by analyzing the HTTP headers sent between the browser and Server.
Cookie-based Session Handling
To enable cookie-based session handling, make sure that web.config file of the web-application contains the following entry:
<sessionState mode="InProc" cookieless="false" timeout="20" />
Let’s say the browser makes a request to a server. This is the first request from the browser to the server. For e.g. for a request: http://localhost/WebApplication1/WebForm1.aspx the HTTP request header sent by the browser would be as shown below:
1. GET /WebApplication1/WebForm1.aspx HTTP/1.1 2. Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* 3. Accept-Language: en-us 4. Accept-Encoding: gzip, deflate 5. User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Avant Browser [avantbrowser.com]; .NET CLR 1.1.4322) 6. Host: localhost 7. Connection: Keep-Alive
Let’s try to understand this header information. The first line shows the type of HTTP request (GET/POST/HEAD) etc, followed by the URL of the resource. The second line declares the MIME type which the browser is capable of handling. The third and fourth lines show the default language and encoding. The fifth line contains information about the browser. This information may be used by the server to identify the browser from where the request is coming. The sixth line contains the address of the server to which the request is made. The seventh line indicates that the browser would keep the connection alive for future requests. The response send back by the server would consist of a HTTP response header and response body. The response header would look something like this:
1. HTTP/1.1 200 OK 2. Server: Microsoft-IIS/5.0 3. Date: Wed, 07 Jan 2004 09:31:07 GMT 4. X-Powered-By: ASP.NET 5. X-AspNet-Version: 1.1.4322 6. Set-Cookie: ASP.NET_SessionId=ll345q550ozqll45qithgi45; path=/ 7. Cache-Control: private 8. Content-Type: text/html; charset=utf-8 Content-Length: 540
Let’s try to understand the line of our interest. The first line indicates the HTTP Status code returned by the Server. “200” Status code indicates that the request was successfully executed. The sixth line shows the cookie that’s send by the Server. This cookie contains the Session ID that is a unique ID generated by the server. The Set-Cookie header instructs the browser to store the cookie in its cache. Now for all further requests this cookie is send back to the server by the browser. For e.g. if the browser clicks on a button of the first page to make a request to WebForm2.aspx, the request header sent would be:
GET /WebApplication1/WebForm2.aspx HTTP/1.1 Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Avant Browser [avantbrowser.com]; .NET CLR 1.1.4322) Host: localhost Connection: Keep-Alive Cookie: ASP.NET_SessionId= ll345q550ozqll45qithgi45
As we can see, the next request the browser makes, it passes the session ID as a cookie back to the Server. The server extracts this session ID from the cookie and maps it to the Session object on the Server side. Thus the session ID is passed to and fro in every request and response. This enables the Server to track a user on the Server side.
Cookie-less Session Handling
For cookie-less Session handling we need to set the ‘cookieless’ attribute to ‘true’ in web.config.
<sessionState mode="InProc" cookieless="true" timeout="20" />
Now let’s make a request, for e.g. http://localhost/WebApplication1/WebForm1.aspx and have a look at the request header. Note: Open a new instance of the web browser, so that the old session ID is used. The request header is as shown below. (Similar to earlier request header in cookie-based session handling)
1. GET /WebApplication1/WebForm1.aspx HTTP/1.1 2. Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* 3. Accept-Language: en-us 4. Accept-Encoding: gzip, deflate 5. User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Avant Browser [avantbrowser.com]; .NET CLR 1.1.4322) 6. Host: localhost 7. Connection: Keep-Alive
But is very interesting to see what the browser returns. The response returned by the browser is as follows
HTTP/1.1 302 Found Server: Microsoft-IIS/5.0 Date: Wed, 07 Jan 2004 10:25:25 GMT X-Powered-By: ASP.NET X-AspNet-Version: 1.1.4322 Location: /WebApplication1/(bcgmybvma1y45czof4me3sq4)/WebForm1.aspx Cache-Control: private Content-Type: text/html; charset=utf-8 Content-Length: 174 <html><head><title>Object moved</title></head><body> <h2>Object moved to <a href='/WebApplication1/(bcgmybvma1y45czof4me3sq4)/WebForm1.aspx'>here</a>.</h2> </body></html>
The first response send by the server contains the HTTP status code: 302 This status code instructs the browser to redirect the request to a new URL specified by the Location attribute in the response header. So the browser makes a second request with the new URL. The Request header it sends would be as shown below:
GET /WebApplication1/(bcgmybvma1y45czof4me3sq4)/WebForm1.aspx HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* Accept-Language: en-us Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Avant Browser [avantbrowser.com]; .NET CLR 1.1.4322) Host: localhost Connection: Keep-Alive
The response received would be an ordinary response with the header as follows:
HTTP/1.1 200 OK Server: Microsoft-IIS/5.0 Date: Wed, 07 Jan 2004 12:02:14 GMT X-Powered-By: ASP.NET X-AspNet-Version: 1.1.4322 Cache-Control: private Content-Type: text/html; charset=utf-8 Content-Length: 557
It’s important to note that in the above response header, the Server has not passed any Session ID cookie to the browser. Now the big question is what happens for future requests. Suppose we have a relative URL in the first page pointing to a second page as shown below:
<body > <form id="form1" action=WebForm2.aspx> <input type=submit ID="Submit1" NAME="Submit1"> </form> </body>
Now when ‘Webform2.aspx’ is requested, then the browser will see that it is a relative URL and automatically make a request for the URL: /WebApplication1/(bcgmybvma1y45czof4me3sq4)/WebForm2.aspx Hence the request header that the browser would send would be:
GET /WebApplication1/( bcgmybvma1y45czof4me3sq4)/WebForm2.aspx HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* Accept-Language: en-us Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Avant Browser [avantbrowser.com]; .NET CLR 1.1.4322) Host: localhost Connection: Keep-Alive
Here it is very important to note that cookie-less session handling would only work with relative URL’s . If the URL given in an absolute URL from the root, then the request would go as a fresh request and another session would be generated for it. For e.g. consider the following URL on a page:
<body > <form id="form1" action=/WebApplication1/WebForm2.aspx> <input type=submit> </form> </body>
The request header sent by the browser would be:
GET /WebApplication1/WebForm2.aspx? HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* Referer: http://localhost/WebApplication1/(otncoribqztxrcqamzn2gfmu)/WebForm1.aspx Accept-Language: en-us Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Avant Browser [avantbrowser.com]; .NET CLR 1.1.4322) Host: localhost Connection: Keep-Alive
As it is a full-path request, the server would again send a 302 Status code with a new generated Session ID for the second page. The response header would be:
HTTP/1.1 302 Found Server: Microsoft-IIS/5.0 Date: Wed, 07 Jan 2004 12:12:04 GMT X-Powered-By: ASP.NET X-AspNet-Version: 1.1.4322 Location: /WebApplication1/(0ryuoc55gxxsdqvhnsmsiy2a)/WebForm2.aspx Cache-Control: private Content-Type: text/html; charset=utf-8 Content-Length: 174 <html><head><title>Object moved</title></head><body> <h2>Object moved to <a href='/WebApplication1/(0ryuoc55gxxsdqvhnsmsiy2a)/WebForm2.aspx'>here</a>.</h2> </body></html>
As we can see, the session ID is a new one, different from one for WebForm1.aspx. Hence URL encoding/mangling cannot be used with full-path URL’s..